package com.hzncc.flowable_diboot.excel.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.diboot.core.util.S;
import com.diboot.file.excel.BaseExcelModel;
import com.diboot.file.excel.listener.FixedHeadExcelListener;
import com.hzncc.flowable_diboot.excel.listener.SimpleCellReadListener;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Log4j2
@Service
public class MultiSheetExcelImportService<T extends BaseExcelModel> {

    /**
     * 读取excel数据
     *
     * @param file          excel文件
     * @param listenerClz   数据处理监听器类
     * @param clz           excel模型类
     * @param headRowNumber 表头行数
     * @return {key:sheetName,value:dataList}
     * @author 陈广煜
     * @date 2024/7/15
     */
    public Map<Integer, List<T>> readExcel(MultipartFile file, Class<T> clz, Class<? extends FixedHeadExcelListener<T>> listenerClz, Integer headRowNumber) {
        ExcelReader reader = null;
        try {
            reader = EasyExcel.read(file.getInputStream()).build();
        } catch (IOException e) {
            throw new RuntimeException("读取excel文件出错:", e);
        }
        List<ReadSheet> readSheets = reader.excelExecutor().sheetList();
        return readSheets.stream().collect(Collectors.toMap(ReadSheet::getSheetNo, readSheet -> {
            FixedHeadExcelListener<T> listener = null;
            try {
                listener = listenerClz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException("实例化listener失败:", e);
            }
            try {
                EasyExcel.read(file.getInputStream(), clz, listener).sheet(readSheet.getSheetNo(), readSheet.getSheetName()).headRowNumber(headRowNumber).doRead();
            } catch (IOException e) {
                throw new RuntimeException("读取excel" + readSheet.getSheetName() + "sheet出错:", e);
            }
            return listener.getDataList();
        }));
    }

    /**
     * 读取指定单元格
     *
     * @param file         excel file
     * @param targetRow    目标行
     * @param targetColumn 目标列
     * @return {key:sheetName,value:stringValue}
     * @throws IOException
     * @author 陈广煜
     * @date 2024/7/15
     */
    public Map<String, String> readCell(MultipartFile file, Integer targetRow, Integer targetColumn) throws IOException {
        Map<String, String> sheetMap = new HashMap<>();
        ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
        List<ReadSheet> readSheets = reader.excelExecutor().sheetList();
        for (ReadSheet readSheet : readSheets) {
            String sheetName = readSheet.getSheetName();
            SimpleCellReadListener listener = new SimpleCellReadListener(targetRow, targetColumn);
            EasyExcel.read(file.getInputStream(), listener).sheet(readSheet.getSheetNo(), sheetName).headRowNumber(0).doRead();
            String cellValue = listener.getCellValue();
            sheetMap.put(sheetName, cellValue);
        }
        return sheetMap;
    }

    /**
     * 读取指定sheet
     *
     * @param file          excel file
     * @param clz           model
     * @param listenerClz
     * @param headRowNumber 表头行数
     * @param sheetName     sheet名称
     * @return 未找到指定页 返回空数组
     * @author 陈广煜
     * @date 2024/7/16
     */
    public List<T> readSheet(MultipartFile file, Class<T> clz, Class<? extends FixedHeadExcelListener<T>> listenerClz, Integer headRowNumber, String sheetName) throws IOException, InstantiationException, IllegalAccessException {
        ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
        List<ReadSheet> readSheets = reader.excelExecutor().sheetList();
        List<T> dataList = new ArrayList<>();
        for (ReadSheet readSheet : readSheets) {
            if (!S.equals(readSheet.getSheetName(), sheetName)) {
                continue;
            }
            FixedHeadExcelListener<T> listener = listenerClz.newInstance();
            EasyExcel.read(file.getInputStream(), clz, listener).sheet(readSheet.getSheetNo(), sheetName).headRowNumber(headRowNumber).doRead();
            dataList = listener.getDataList();
            return dataList;
        }
        return dataList;
    }

    // 读取指定sheet页的指定单元格
    public String readCell(MultipartFile file, Integer targetRow, Integer targetColumn, String sheetName) throws IOException {
        ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
        List<ReadSheet> readSheets = reader.excelExecutor().sheetList();
        String cellValue = "";
        for (ReadSheet readSheet : readSheets) {
            if (!S.equals(readSheet.getSheetName(), sheetName)) {
                continue;
            }
            SimpleCellReadListener listener = new SimpleCellReadListener(targetRow, targetColumn);
            EasyExcel.read(file.getInputStream(), listener).sheet(readSheet.getSheetNo(), sheetName).headRowNumber(0).doRead();
            cellValue = listener.getCellValue();
        }
        reader.close();
        return cellValue;
    }

    public List<T> readSheetBySheetNo(MultipartFile file, Class<T> clz, Class<? extends FixedHeadExcelListener<T>> listenerClz, Integer headRowNumber, Integer sheetNo) throws IOException, InstantiationException, IllegalAccessException {
        ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
        List<ReadSheet> readSheets = reader.excelExecutor().sheetList();
        List<T> dataList = new ArrayList<>();
        for (ReadSheet readSheet : readSheets) {
            if (!readSheet.getSheetNo().equals(sheetNo)) {
                continue;
            }
            FixedHeadExcelListener<T> listener = listenerClz.newInstance();
            EasyExcel.read(file.getInputStream(), clz, listener).sheet(readSheet.getSheetNo(), readSheet.getSheetName()).headRowNumber(headRowNumber).doRead();
            dataList = listener.getDataList();
        }
        return dataList;
    }

    /**
     * 读取单个sheet
     *
     * @param file
     * @param clz
     * @param listenerClz
     * @return
     */
    public List<T> readSingleSheet(MultipartFile file, Class<T> clz, Class<? extends FixedHeadExcelListener<T>> listenerClz) throws IOException, InstantiationException, IllegalAccessException {
        ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
        ReadSheet readSheet = reader.excelExecutor().sheetList().get(0);
        List<T> dataList = new ArrayList<>();
        FixedHeadExcelListener<T> listener = listenerClz.newInstance();
        EasyExcel.read(file.getInputStream(), clz, listener).sheet(readSheet.getSheetNo(), readSheet.getSheetName()).headRowNumber(1).doRead();
        dataList = listener.getDataList();
        return dataList;
    }
}